home *** CD-ROM | disk | FTP | other *** search
- /* this hacked up ver by jrd, as we don't do core on an ST (they use RAMs) :-}
- and out executable files are different. */
-
- /* Work with core dump and executable files, for GDB.
- Copyright (C) 1986, 1987 Free Software Foundation, Inc.
-
- GDB is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY. No author or distributor accepts responsibility to anyone
- for the consequences of using it or for whether it serves any
- particular purpose or works at all, unless he says so in writing.
- Refer to the GDB General Public License for full details.
-
- Everyone is granted permission to copy, modify and redistribute GDB,
- but only under the conditions described in the GDB General Public
- License. A copy of this license is supposed to have been given to you
- along with GDB so you can know your rights and responsibilities. It
- should be in a file named COPYING. Among other things, the copyright
- notice and this notice must be preserved on all copies.
-
- In other words, go ahead and share GDB, but don't try to stop
- anyone else from sharing it farther. Help stamp out software hoarding!
- */
-
- #include "defs.h"
- #include "param.h"
-
- #include <st-out.h>
- #include <types.h>
- #include <stdio.h>
- #include <signal.h>
- #include <param.h>
- /* #include <dir.h> */
- #include <file.h>
- #include <stat.h>
-
- /* Hook for `exec_file_command' command to call. */
-
- void (*exec_file_display_hook) ();
-
- /* File names of core file and executable file. */
-
- static char *corefile;
- static char *execfile;
-
- /* Descriptors on which core file and executable file are open.
- Note that the execchan is closed when an inferior is created
- and reopened if the inferior dies or is killed. */
-
- static int corechan;
- static int execchan;
-
- /* Last modification time of executable file.
- Also used in source.c to compare against mtime of a source file. */
-
- int exec_mtime;
-
- /* Virtual addresses of bounds of the two areas of memory in the core file. */
-
- static CORE_ADDR data_start;
- static CORE_ADDR data_end;
- static CORE_ADDR stack_start;
- static CORE_ADDR stack_end;
-
- /* Virtual addresses of bounds of two areas of memory in the exec file.
- Note that the data area in the exec file is used only when there is no core file. */
-
- CORE_ADDR text_start;
- CORE_ADDR text_end;
-
- static CORE_ADDR exec_data_start;
- static CORE_ADDR exec_data_end;
-
- /* Address in executable file of start of text area data. */
-
- static int text_offset;
-
- /* Address in executable file of start of data area data. */
-
- static int exec_data_offset;
-
- /* Address in core file of start of data area data. */
-
- static int data_offset;
-
- /* Address in core file of start of stack area data. */
-
- static int stack_offset;
-
- #ifdef COFF_FORMAT
- /* various coff data structures */
-
- static FILHDR file_hdr;
- static SCNHDR text_hdr;
- static SCNHDR data_hdr;
-
- #endif /* not COFF_FORMAT */
-
- /* a.out header of exec file. */
-
- static struct aexec exec_aouthdr;
-
- static void validate_files ();
- unsigned int register_addr ();
-
- core_file_command (filename, from_tty)
- char *filename;
- int from_tty;
- {
- fprintf_filtered(stderr, "Not on an ST you don't\n");
- }
-
- exec_file_command (filename, from_tty)
- char *filename;
- int from_tty;
- {
- int val;
-
- /* Eliminate all traces of old exec file.
- Mark text segment as empty. */
-
- if (execfile)
- free (execfile);
- execfile = 0;
- data_start = 0;
- data_end -= exec_data_start;
- text_start = 0;
- text_end = 0;
- exec_data_start = 0;
- exec_data_end = 0;
- if (execchan >= 0)
- close (execchan);
- execchan = -1;
-
- /* Now open and digest the file the user requested, if any. */
-
- if (filename)
- {
- execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
- &execfile);
- if (execchan < 0)
- perror_with_name (filename);
-
- #ifdef COFF_FORMAT
- {
- int aout_hdrsize;
- int num_sections;
-
- if (read_file_hdr (execchan, &file_hdr) < 0)
- error ("\"%s\": not in executable format.", execfile);
-
- aout_hdrsize = file_hdr.f_opthdr;
- num_sections = file_hdr.f_nscns;
-
- if (read_aout_hdr (execchan, &exec_aouthdr, aout_hdrsize) < 0)
- error ("\"%s\": can't read optional aouthdr", execfile);
-
- if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections) < 0)
- error ("\"%s\": can't read text section header", execfile);
-
- if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections) < 0)
- error ("\"%s\": can't read data section header", execfile);
-
- text_start = exec_aouthdr.text_start;
- text_end = text_start + exec_aouthdr.tsize;
- text_offset = text_hdr.s_scnptr;
- exec_data_start = exec_aouthdr.data_start;
- exec_data_end = exec_data_start + exec_aouthdr.dsize;
- exec_data_offset = data_hdr.s_scnptr;
- data_start = exec_data_start;
- data_end += exec_data_start;
- exec_mtime = file_hdr.f_timdat;
- }
- #else /* not COFF_FORMAT */
- {
- struct stat st_exec;
-
- #ifdef gould
- FILHDR exec_coffhdr;
-
- val = myread (execchan, &exec_coffhdr, sizeof exec_coffhdr);
- if (val < 0)
- perror_with_name (filename);
- #endif
- val = myread (execchan, &exec_aouthdr, sizeof (struct aexec));
-
- if (val < 0)
- perror_with_name (filename);
-
- text_start = A_TXTOFF (exec_aouthdr);
- exec_data_start = A_DATOFF (exec_aouthdr);
- #ifdef gould
- text_offset = N_TXTOFF (exec_coffhdr, exec_aouthdr);
- exec_data_offset = N_TXTOFF (exec_coffhdr, exec_aouthdr)
- + exec_aouthdr.a_text;
- #else
- text_offset = A_TXTOFF (exec_aouthdr);
- exec_data_offset = A_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text;
- #endif
- text_end = text_start + exec_aouthdr.a_text;
- exec_data_end = exec_data_start + exec_aouthdr.a_data;
- data_start = exec_data_start;
- data_end += exec_data_start;
-
- /*
- fstat (execchan, &st_exec);
- exec_mtime = st_exec.st_mtime;
- */
- }
- #endif /* not COFF_FORMAT */
-
- validate_files ();
- }
- else if (from_tty)
- printf_filtered ("No exec file now.\n");
-
- /* Tell display code (if any) about the changed file name. */
- if (exec_file_display_hook)
- (*exec_file_display_hook) (filename);
- }
-
- /* Call this to specify the hook for exec_file_command to call back.
- This is called from the x-window display code. */
-
- specify_exec_file_hook (hook)
- void (*hook) ();
- {
- exec_file_display_hook = hook;
- }
-
- /* The exec file must be closed before running an inferior.
- If it is needed again after the inferior dies, it must
- be reopened. */
-
- close_exec_file ()
- {
- if (execchan >= 0)
- close (execchan);
- execchan = -1;
- }
-
- reopen_exec_file ()
- {
- if (execchan < 0 && execfile != 0)
- {
- char *filename = concat (execfile, "", "");
- exec_file_command (filename, 0);
- free (filename);
- }
- }
-
- /* If we have both a core file and an exec file,
- print a warning if they don't go together.
- This should really check that the core file came
- from that exec file, but I don't know how to do it. */
-
- static void
- validate_files ()
- {
- }
-
- /* Return the name of the executable file as a string.
- ERR nonzero means get error if there is none specified;
- otherwise return 0 in that case. */
-
- char *
- get_exec_file (err)
- int err;
- {
- if (err && execfile == 0)
- error ("No executable file specified.\n\
- Use the \"exec-file\" and \"symbol-file\" commands.");
- return execfile;
- }
-
- int
- have_core_file_p ()
- {
- return(0);
- }
-
- static void
- files_info ()
- {
- char *symfile;
- extern char *get_sym_file ();
-
- if (execfile)
- printf_filtered ("Executable file \"%s\".\n", execfile);
- else
- printf_filtered ("No executable file\n");
-
- if (have_inferior_p ())
- printf_filtered ("Using the running image of the program, rather than these files.\n");
-
- symfile = get_sym_file ();
- if (symfile != 0)
- printf_filtered ("Symbols loaded from \"%s\".\n", symfile);
-
- if (! have_inferior_p ())
- {
- if (execfile)
- {
- printf_filtered ("Text segment from 0x%x to 0x%x.\n",
- text_start, text_end);
- }
- }
- }
-
- /* Read "memory data" from core file and/or executable file */
-
- read_memory (memaddr, myaddr, len)
- CORE_ADDR memaddr;
- char *myaddr;
- int len;
- {
- /* fprintf_filtered(stderr, "read-memory(%X, %X, %d) inf %d\n", memaddr, myaddr, len,
- have_inferior_p()); */
- if (have_inferior_p ())
- read_inferior_memory (memaddr, myaddr, len);
- else
- xfer_core_file (memaddr, myaddr, len, 0);
- }
-
- /* Write LEN bytes of data starting at address MYADDR
- into debugged program memory at address MEMADDR.
- Returns zero if successful, or an errno value if ptrace failed.